if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }
    var aArgs = Array.prototype.slice.call(arguments, 1),
      fToBind = this,
      fNOP = function () {},
      fBound = function () {
        return fToBind.apply(this instanceof fNOP && oThis
            ? this
            : oThis,
          aArgs.concat(Array.prototype.slice.call(arguments)));
      };
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
  };
}

define(['jquery', 'config'], function($, Config) {

  var LoadingInstance;
  function Loading() {
    // 单例
    return LoadingInstance;
  }

  $.extend(Loading.prototype, {

    template: '',

    loadings: [],

    timeout: 20 * 1000,

    create: function(context) {
      // 只能在 panel-body 里创建 loading
      if (!context || !context.is || !context.is('.panel-body') || context.is('.messager-body')) return;
      return $(this.template).appendTo(context);
    },

    add: function(context) {
      var loading = this.create(context);
      var vm = this;

      if (loading) {
        // 压入清除 loading 方法
        this.loadings.unshift(function unLoading() {
          loading.fadeOut(vm.pop.bind(vm))
        });

        // 确保不会因为意外而造成loading无法消失
        setTimeout(vm.pop.bind(vm), vm.timeout)
      }
    },

    pop: function() {
      var unLoading = this.loadings.pop();

      if (typeof unLoading === 'function') {
        unLoading()
      }
    }
  });

  return LoadingInstance = new Loading();
});
